﻿using Dapper;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using YAKEJI.Abp.Database;
using YAPACS.BusinessObjects.Managements.Exams;
using YAPACS.RisServer.Services.Dtos;
using YAPACS.Workflows;

namespace YAPACS.RisServer.Workflows.ArchiveExam;

public class GetArchiveExamList(IRepository<ExamArchiving, Guid> examArchiving, IDatabaseConnectionProvider connectionProvider) : WorkflowBase, IGetArchiveExamList, ITransientDependency
{
    private readonly IRepository<ExamArchiving, Guid> _examArchiving = examArchiving;
    private readonly IDatabaseConnectionProvider _connectionProvider = connectionProvider;


    protected override async Task<WorkflowOutput> InvokeCoreAsync(WorkflowInput input)
    {
        if (input.ContainsKey("Columns") && input.GetValueOrDefault("Columns") is Column[] columns)
        {
            if (input.ContainsKey("DataGridRequest") && input.GetValueOrDefault("DataGridRequest") is DataGridRequest request)
            {
                return await GetArchiveListAsync(columns, request, input);
            }
        }
        return new WorkflowOutput
        {
            Success = false
        };
    }

    private async Task<WorkflowOutput> GetArchiveListAsync(Column[] columns, DataGridRequest request, WorkflowInput input)
    {
        if (request.UserData.Count > 0)
        {
            string examTimeRange = request.UserData["examTimeRange"]?.ToString();
            var timeRange = examTimeRange.Split(',');
            var startTime = DateTime.Parse(timeRange[0]).Date;
            var endTime = DateTime.Parse(timeRange[1]).AddDays(1).Date;
            var archive = await _examArchiving.FirstOrDefaultAsync(e => e.IsActive && (startTime >= e.StartTime && startTime <= e.EndTime) || (endTime >= e.StartTime && endTime <= e.EndTime));

            if (archive != null && request.Take > 0)
            {
                const string key = "ArchiveOutput";
                string condition = "";
                if (input.ContainsKey(key) && input.GetValueOrDefault(key) is string criteria)
                {
                    condition = criteria;
                }
                request.UserData["startTime"] = startTime < archive.StartTime ? archive.StartTime : startTime;
                request.UserData["endTime"] = endTime > archive.EndTime ? archive.EndTime : endTime;

                using var connection = _connectionProvider.GetDbConnection(archive.ConnectionString, databaseType: archive.DatabaseType);
                if (connection.State == System.Data.ConnectionState.Closed)
                {
                    connection.Open();
                }
                //根据获取到的表头查询列表
                var _columns = columns.ToList();
                if (!_columns.Any(e => e.ArchiveProperty == "reportUrl" || e.DataField == "reportUrl"))
                {
                    _columns.Add(new Column
                    {
                        DataField = "reportUrl",
                        ArchiveProperty = "CONCAT(ReportUrlBase,ReportUrl)"
                    });
                }
                if (!_columns.Any(e => e.ArchiveProperty == "reportImagesPath" || e.DataField == "reportImagesPath"))
                {
                    _columns.Add(new Column
                    {
                        DataField = "reportImagesPath",
                        ArchiveProperty = "CONCAT(ReportImagesPathBase,ReportImagesPath)"
                    });
                }
                columns = _columns.ToArray();
                var selectStr = columns.GetArchiveColumnString();
                if (request.Sort != null && request.Sort.Count > 0)
                {
                    foreach (var sort in request.Sort)
                    {
                        var column = columns.Where(e => e.DataField == sort.Selector).FirstOrDefault();
                        if (column != null)
                        {
                            if (!string.IsNullOrWhiteSpace(column.ArchiveOrder))
                            {
                                sort.Selector = column.ArchiveOrder;
                            }
                            else if (!string.IsNullOrWhiteSpace(column.ArchiveProperty))
                            {
                                sort.Selector = column.ArchiveProperty;
                            }
                        }
                    }
                }
                else
                {
                    request.Sort = [new() { Selector = "Oid", Desc = true }];
                }
                var _sort = request.Sort.First();
                string sql = "";
                if (archive.DatabaseType == DatabaseType.SqlServer)
                {
                    sql = $"select {selectStr} from {archive.TableName} {condition} order by {_sort.Selector} {(_sort.Desc ? "desc" : "asc")} offset {request.Skip} rows fetch next {request.Take} rows only";
                }
                else
                {
                    sql = $"select {selectStr} from {archive.TableName} {condition} order by {_sort.Selector} {(_sort.Desc ? "desc" : "asc")} limit {request.Take} offset {request.Skip}";
                }
                Console.WriteLine($"sql:{sql}");
                var list = await connection.QueryAsync(sql, request.UserData);
                var count = await connection.ExecuteScalarAsync<int>($"select count(1) from {archive.TableName} {condition}", request.UserData);
                return new WorkflowOutput()
                {
                    Success = true,
                    Data = new DataGridDto()
                    {
                        Rows = list,
                        TotalCount = count
                    }
                };
            }
        }
        return new WorkflowOutput
        {
            Success = false
        };
    }
}
